import numpy as np
from . import LocalSearchOperator, register_operator


class DoubleBridgeMoveOperator(LocalSearchOperator):
    """Double-Bridge Move局部搜索算子，用于跳出局部最优"""

    def __init__(self):
        self.name = "double_bridge"
        self.supported_problems = ["tsp"]

    def apply_double_bridge(self, solution):
        """应用双桥移动"""
        n = len(solution)

        # 随机选择四个断点 (i, j, k, l)，满足 0 < i < j < k < l < n
        i = np.random.randint(1, n - 6)
        j = np.random.randint(i + 2, n - 4)
        k = np.random.randint(j + 2, n - 2)
        l = np.random.randint(k + 2, n)

        # 创建新解：A-B-C-D -> A-D-C-B
        # 分段: A = [0:i], B = [i:j], C = [j:k], D = [k:l], E = [l:]
        new_solution = np.concatenate([
            solution[0:i],  # 段A
            solution[k:l],  # 段D
            solution[j:k],  # 段C
            solution[i:j],  # 段B
            solution[l:]  # 段E
        ])

        return new_solution

    def __call__(self, solution, problem_instance, intensity=5):
        """应用Double-Bridge Move"""
        if not self.is_applicable(problem_instance):
            return solution, 0

        best_solution = solution.copy()
        best_cost = problem_instance.evaluate(best_solution)

        # Double-Bridge Move通常用于扰动而非改进，所以我们尝试多次并选择最好的
        for _ in range(intensity):
            new_solution = self.apply_double_bridge(solution)
            new_cost = problem_instance.evaluate(new_solution)

            if new_cost < best_cost:
                best_solution = new_solution
                best_cost = new_cost

        improvement = problem_instance.evaluate(solution) - best_cost
        return best_solution, improvement


# 注册算子
register_operator("double_bridge", DoubleBridgeMoveOperator())